# -*- coding: utf-8 -*-
"""
2021-4-8

@author: 李运辰

公众号：python研究者
"""
import requests
import time
import json
import os
import pandas as pd

#matplotlib 画图
import matplotlib
matplotlib.use('Agg')
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#解决中文显示问题
###plt.rcParams['font.sans-serif'] = ['KaiTi'] # window下使用指定默认字体
#设置字体为楷体
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] ### mac下使用

#统计并排序
from collections import Counter

#词云图
from stylecloud import gen_stylecloud
import jieba
#pyecharts
from pyecharts import options as opts
from pyecharts.globals import ThemeType
from pyecharts.charts import Bar, Pie, Timeline, Graph, Map ,Line ,Funnel


from flask_cors import *
from flask import Flask,render_template,request,Response,redirect,url_for
#内网ip
app = Flask(__name__)
CORS(app, supports_credentials=True)
#####################画图
#读取数据
def readdata(filepath):
    if "csv" in filepath:
        df = pd.read_csv(filepath, encoding='gbk', engine='python')
    else:
        df = pd.read_excel(filepath)
    return df
# 绘制词云图
@app.route('/startdraw', methods=['POST', 'GET'])
def startdraw():
    filepath = request.args.get('filepath')
    rowe = request.args.get('rowe')
    bc = request.args.get('bc')
    bcolor = "white"
    if str(bc)=="2":
        bcolor = "black"
    # 读入数据
    df = readdata(filepath)
    contents = (df[rowe]).tolist()
    text = "".join(map(str, contents))
    with open("stopword.txt", "r", encoding='UTF-8') as f:
        stopword = f.readlines()
    for i in stopword:

        i = str(i).replace("\r\n", "").replace("\r", "").replace("\n", "")
        text = text.replace(i, "")
    word_list = jieba.cut(text)
    result = " ".join(word_list)  # 分词用 隔开
    # 制作中文云词
    icon_name = 'fab fa-weixin'
    basepath = os.path.dirname(__file__)  # 当前文件所在路径
    dir = str(time.strftime('%y%m%d', time.localtime()))
    upload_path = os.path.join(basepath, 'static/img/' + dir)
    # 判断文件夹是否存在
    if not os.path.exists(upload_path):
        os.mkdir(upload_path)
    file_name = str(round(time.time() * 1000))
    gen_stylecloud(text=result, icon_name=icon_name, font_path='simsun.ttc',background_color=bcolor,
                   output_name=upload_path+"/"+str(file_name)+".png")  # 必须加中文字体，否则格式错误
    return Response(json.dumps('static/img/' + dir+"/"+str(file_name)+".png"), mimetype='application/json')
# 绘制柱状图
@app.route('/drawzzt', methods=['POST', 'GET'])
def drawzzt():
    filepath = request.args.get('filepath')
    rowx = request.args.get('rowx')
    rowy = request.args.get('rowy')
    exceltitle = request.args.get('exceltitle')

    # filepath = "uploads/210809/1628498275306柱状图样例数据.xlsx"
    # rowx = "类别"
    # rowy = "数量"
    # exceltitle = "123"


    # 读入数据
    df = readdata(filepath)
    key = (df[rowx]).tolist()
    value = (df[rowy]).tolist()
    # 路径
    basepath = os.path.dirname(__file__)  # 当前文件所在路径
    dir = str(time.strftime('%y%m%d', time.localtime()))
    upload_path = os.path.join(basepath, 'static/img/' + dir)
    # 判断文件夹是否存在
    if not os.path.exists(upload_path):
        os.mkdir(upload_path)
    file_name = str(round(time.time() * 1000))

    # 链式调用
    c = (
        Bar(
            init_opts=opts.InitOpts(  # 初始配置项
                theme=ThemeType.MACARONS,
                animation_opts=opts.AnimationOpts(
                    animation_delay=1000, animation_easing="cubicOut"  # 初始动画延迟和缓动效果
                ))
        )
            .add_xaxis(xaxis_data=key)  # x轴
            .add_yaxis(series_name=str(exceltitle), y_axis=value)  # y轴
            .set_global_opts(
            title_opts=opts.TitleOpts(title='', subtitle='',  # 标题配置和调整位置
                                      title_textstyle_opts=opts.TextStyleOpts(
                                          font_family='SimHei', font_size=25, font_weight='bold', color='red',
                                      ), pos_left="90%", pos_top="10",
                                      ),
            xaxis_opts=opts.AxisOpts(name=str(rowx), axislabel_opts=opts.LabelOpts(rotate=45)),
            # 设置x名称和Label rotate解决标签名字过长使用
            yaxis_opts=opts.AxisOpts(name=str(rowy)),

        )

    )
    c.render(path=upload_path+"/"+str(file_name)+".html")
    return Response(json.dumps('static/img/' + dir+"/"+str(file_name)+".html"), mimetype='application/json')
# 绘制饼图
@app.route('/drawbt', methods=['POST', 'GET'])
def drawbt():
    filepath = request.args.get('filepath')
    rowx = request.args.get('rowx')
    rowy = request.args.get('rowy')
    exceltitle = request.args.get('exceltitle')
    # 读入数据
    df = readdata(filepath)
    key = (df[rowx]).tolist()
    value = (df[rowy]).tolist()
    # 路径
    basepath = os.path.dirname(__file__)  # 当前文件所在路径
    dir = str(time.strftime('%y%m%d', time.localtime()))
    upload_path = os.path.join(basepath, 'static/img/' + dir)
    # 判断文件夹是否存在
    if not os.path.exists(upload_path):
        os.mkdir(upload_path)
    file_name = str(round(time.time() * 1000))

    # 链式调用
    c = (
        Pie()
            .add("", [list(z) for z in zip(key, value)])
            .set_colors(["blue", "green", "yellow", "red", "pink", "orange", "purple"])
            .set_global_opts(title_opts=opts.TitleOpts(title=str(exceltitle)))
            .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
    )
    c.render(path=upload_path+"/"+str(file_name)+".html")
    return Response(json.dumps('static/img/' + dir+"/"+str(file_name)+".html"), mimetype='application/json')
# 绘制关系图
@app.route('/drawgxt', methods=['POST', 'GET'])
def drawgxt():
    filepath = request.args.get('filepath')
    rowx = request.args.get('rowx')
    rowy = request.args.get('rowy')
    exceltitle = request.args.get('exceltitle')
    # 读入数据
    df = readdata(filepath)
    key = (df[rowx]).tolist()
    value = (df[rowy]).tolist()
    # 路径
    basepath = os.path.dirname(__file__)  # 当前文件所在路径
    dir = str(time.strftime('%y%m%d', time.localtime()))
    upload_path = os.path.join(basepath, 'static/img/' + dir)
    # 判断文件夹是否存在
    if not os.path.exists(upload_path):
        os.mkdir(upload_path)
    file_name = str(round(time.time() * 1000))
    sum = 0
    for k in value:
        sum = sum+int(k)
    values = []
    for k in value:
        values.append(int(int(k)/sum*100))
    # 链式调用
    # nodes = [
    #     {"name": "结点1", "symbolSize": 10},
    #     {"name": "结点2", "symbolSize": 20},
    #     {"name": "结点3", "symbolSize": 30},
    #     {"name": "结点4", "symbolSize": 40},
    #     {"name": "结点5", "symbolSize": 50},
    #     {"name": "结点6", "symbolSize": 40},
    #     {"name": "结点7", "symbolSize": 30},
    #     {"name": "结点8", "symbolSize": 20},
    # ]
    nodes = []
    for i in range(0,len(key)):
        tem = {"name": str(key[i]), "symbolSize": int(values[i])}
        nodes.append(tem)
    links = []
    print(nodes)
    for i in nodes:
        for j in nodes:
            links.append({"source": i.get("name"), "target": j.get("name")})
    c = (
        Graph()
            .add("", nodes, links, repulsion=8000)
            .set_global_opts(title_opts=opts.TitleOpts(title=str(exceltitle)))
    )
    c.render(path=upload_path+"/"+str(file_name)+".html")
    return Response(json.dumps('static/img/' + dir+"/"+str(file_name)+".html"), mimetype='application/json')
# 绘制折线图
@app.route('/drawzxt', methods=['POST', 'GET'])
def drawzxt():
    filepath = request.args.get('filepath')
    rowx = request.args.get('rowx')
    rowy = request.args.get('rowy')
    exceltitle = request.args.get('exceltitle')
    # 读入数据
    df = readdata(filepath)
    key = (df[rowx]).tolist()
    value = (df[rowy]).tolist()
    # 路径
    basepath = os.path.dirname(__file__)  # 当前文件所在路径
    dir = str(time.strftime('%y%m%d', time.localtime()))
    upload_path = os.path.join(basepath, 'static/img/' + dir)
    # 判断文件夹是否存在
    if not os.path.exists(upload_path):
        os.mkdir(upload_path)
    file_name = str(round(time.time() * 1000))
    c = (
        Line()
            .add_xaxis(key)
            .add_yaxis(str(rowx), value, is_connect_nones=True)
            .set_global_opts(title_opts=opts.TitleOpts(title=str(exceltitle)))
    )
    c.render(path=upload_path+"/"+str(file_name)+".html")
    return Response(json.dumps('static/img/' + dir+"/"+str(file_name)+".html"), mimetype='application/json')
# 绘制中国地图
@app.route('/drawmap1', methods=['POST', 'GET'])
def drawmap1():
    filepath = request.args.get('filepath')
    rowx = request.args.get('rowx')
    rowy = request.args.get('rowy')
    exceltitle = request.args.get('exceltitle')
    # 读入数据
    df = readdata(filepath)
    key = (df[rowx]).tolist()
    value = (df[rowy]).tolist()
    # 路径
    basepath = os.path.dirname(__file__)  # 当前文件所在路径
    dir = str(time.strftime('%y%m%d', time.localtime()))
    upload_path = os.path.join(basepath, 'static/img/' + dir)
    # 判断文件夹是否存在
    if not os.path.exists(upload_path):
        os.mkdir(upload_path)
    file_name = str(round(time.time() * 1000))
    # 开始画图
    max = 0
    for i in value:
        if int(i)>max:
            max = int(i)

    c = (
        Map()
            .add(str(exceltitle), [list(z) for z in zip(key, value)], "china")
            .set_global_opts(
            title_opts=opts.TitleOpts(title=str(exceltitle)),
            visualmap_opts=opts.VisualMapOpts(max_=max, is_piecewise=True),
        )
    )
    c.render(path=upload_path+"/"+str(file_name)+".html")
    return Response(json.dumps('static/img/' + dir+"/"+str(file_name)+".html"), mimetype='application/json')
# 绘制城市地图
@app.route('/drawmap2', methods=['POST', 'GET'])
def drawmap2():
    filepath = request.args.get('filepath')
    rowx = request.args.get('rowx')
    rowy = request.args.get('rowy')
    city = request.args.get('city')
    exceltitle = request.args.get('exceltitle')
    # 读入数据
    df = readdata(filepath)
    key = (df[rowx]).tolist()
    value = (df[rowy]).tolist()
    # 路径
    basepath = os.path.dirname(__file__)  # 当前文件所在路径
    dir = str(time.strftime('%y%m%d', time.localtime()))
    upload_path = os.path.join(basepath, 'static/img/' + dir)
    # 判断文件夹是否存在
    if not os.path.exists(upload_path):
        os.mkdir(upload_path)
    file_name = str(round(time.time() * 1000))
    # 开始画图
    max = 0
    for i in value:
        if int(i) > max:
            max = int(i)
    c = (
        Map()
            .add(str(exceltitle), [list(z) for z in zip(key, value)], str(city))
            .set_global_opts(
            title_opts=opts.TitleOpts(title=str(city)+"地图"),
            visualmap_opts=opts.VisualMapOpts(max_=max, is_piecewise=True),
        )
    )
    c.render(path=upload_path+"/"+str(file_name)+".html")
    return Response(json.dumps('static/img/' + dir+"/"+str(file_name)+".html"), mimetype='application/json')
# 绘制漏斗图
@app.route('/drawldt', methods=['POST', 'GET'])
def drawldt():
    filepath = request.args.get('filepath')
    rowx = request.args.get('rowx')
    rowy = request.args.get('rowy')
    exceltitle = request.args.get('exceltitle')
    # 读入数据
    df = readdata(filepath)
    key = (df[rowx]).tolist()
    value = (df[rowy]).tolist()
    # 路径
    basepath = os.path.dirname(__file__)  # 当前文件所在路径
    dir = str(time.strftime('%y%m%d', time.localtime()))
    upload_path = os.path.join(basepath, 'static/img/' + dir)
    # 判断文件夹是否存在
    if not os.path.exists(upload_path):
        os.mkdir(upload_path)
    file_name = str(round(time.time() * 1000))
    # 开始画图
    c = (
        Funnel()
            .add(str(rowx), [list(z) for z in zip(key, value)])
            .set_global_opts(title_opts=opts.TitleOpts(title=str(exceltitle)))
    )
    c.render(path=upload_path+"/"+str(file_name)+".html")
    return Response(json.dumps('static/img/' + dir+"/"+str(file_name)+".html"), mimetype='application/json')

def cp(c_text,c_count,percentage,upload_path):
    fig, ax1 = plt.subplots(figsize=(15, 10))
    x = np.arange(len(c_text))
    y = np.array(list(c_count))
    xticks1 = list(c_text)
    # # 上面这两条语句，是用来设置条形图的颜色的，前6条柱子是gray色，而后四条是蓝绿色
    plt.bar(x, y, width=0.45, label='female', align='center', color='c', alpha=0.9)
    # plt.bar(x, w, bottom=vbar1, label='male', tick_label=vbar1, width=0.45, align='center', color='y', alpha=0.9)
    # 看我斜体数据，就是关键了
    plt.xticks(x, xticks1, size='medium')
    # 打印下方条形图的数据
    for a, b in zip(x, y):
        plt.text(a, b, '%s' % b, ha='center', va='bottom', fontsize=10)
    # 折线图
    ax2 = ax1.twinx()
    z = np.array(list(percentage))
    ax2.plot(x, z, c='y', marker='o')
    # 打印折线图的数据
    for a, b in zip(x, z):
        plt.text(a, b, '%s' % b, ha='center', va='bottom', fontsize=10)
    # 保存成图片
    cp_name = str(round(time.time() * 1000))
    plt.savefig(upload_path + "/" + str(cp_name)+".png", format='png')
    return str(cp_name)+".png"

# 绘制词频统计之词频
@app.route('/startcptj', methods=['POST', 'GET'])
def startcptj():
    filepath = request.args.get('filepath')
    # excel 字段
    rowe = request.args.get('rowe')
    # 词云图背景
    bc = request.args.get('bc')
    # 统计词频排名在前的多少个词
    cp_count = int(request.args.get('cp_count'))
    bcolor = "white"
    if str(bc)=="2":
        bcolor = "black"
    # 读入数据
    df = readdata(filepath)
    contents = (df[rowe]).tolist()
    text = "".join(map(str, contents))
    with open("stopword.txt", "r", encoding='UTF-8') as f:
        stopword = f.readlines()
    for i in stopword:

        i = str(i).replace("\r\n", "").replace("\r", "").replace("\n", "")
        text = text.replace(i, "")
    word_list = jieba.cut(text)
    ############################词云图############################
    result = " ".join(word_list)  # 分词用 隔开
    # 制作中文云词
    icon_name = 'fab fa-weixin'
    basepath = os.path.dirname(__file__)  # 当前文件所在路径
    dir = str(time.strftime('%y%m%d', time.localtime()))
    upload_path = os.path.join(basepath, 'static/img/' + dir)
    # 判断文件夹是否存在
    if not os.path.exists(upload_path):
        os.mkdir(upload_path)
    file_name = str(round(time.time() * 1000))
    gen_stylecloud(text=result, icon_name=icon_name, font_path='simsun.ttc',background_color=bcolor,
                   output_name=upload_path+"/"+str(file_name)+".png")  # 必须加中文字体，否则格式错误

    ############################词频############################
    clear_word = result.split(" ")
    c_word = [i for i in clear_word if len(i) > 1]
    c_result = Counter(c_word)
    # 排序
    d = sorted(c_result.items(), key=lambda x: x[1], reverse=True)
    t = [i[0] for i in d]
    v = [i[1] for i in d]
    c_text = t
    c_count = v
    if len(t)>cp_count:
        c_text = t[0:cp_count]
        c_count = v[0:cp_count]
    # #text = ['校区', '大道', '经济', '东路', '西路', '开发区', '南路', '山东省', '园区', '江苏省', '四川省', '河北省']  # 横坐标的内容
    # #count = [632, 474, 161, 156, 146, 135, 130, 130, 128, 128, 118, 116]  # 个数
    percentage = []  # 百分比
    sum = 0
    for i in c_count:
        sum = sum + int(i)
    for i in c_count:
        percentage.append(float("%.1f" % (int(i) / sum * 100)))
    try:
        cp_path = cp(c_text,c_count,percentage,upload_path)
    except:
        pass
    res = []
    # 词云图路径
    res.append(['static/img/' + dir+"/"+str(file_name)+".png"])
    # 词频图路径
    res.append(['static/img/' + dir + "/" + str(cp_path)])
    # 词频内容
    res.append(c_text)
    # 词频个数
    res.append(c_count)
    # 百分比
    res.append(percentage)
    return Response(json.dumps(res), mimetype='application/json')








############################flask路由
#进入首页
@app.route('/')
def index():
    return render_template('index.html')
# 词云图上传excel
@app.route('/upload_file', methods=['POST', 'GET'])
def upload():
    if request.method == 'POST':
        f = request.files['file']
        basepath = os.path.dirname(__file__)  # 当前文件所在路径
        print(f.filename)
        #######################################
        # 毫秒级时间戳
        file_name = str(round(time.time() * 1000))
        dir = str(time.strftime('%y%m%d', time.localtime()))
        upload_path = os.path.join(basepath, 'uploads/'+dir)
        # 判断文件夹是否存在
        if not os.path.exists(upload_path):
            os.mkdir(upload_path)
        #######################################
        file_path = str(file_name)+str(f.filename)
        f.save(upload_path+"/"+file_path)
    return Response(json.dumps('uploads/'+dir+"/"+file_path), mimetype='application/json')
###获取（传递）参数
@app.route('/alldata', methods=['POST', 'GET'])
def alldata():
    filepath = request.args.get('filepath')
    #filepath = "uploads/210806/1628239858573全国大学数据-李运辰.xls"
    df = readdata(filepath)
    head = df.columns.to_list()
    list = df.values.tolist()
    lists = []
    lenth = 15
    if len(list)<lenth:
        lenth = len(list)
    for i in range(0, lenth):
        dictk = {}
        for j in range(0, len(head)):
            dictk[head[j]] = str(list[i][j])
        lists.append(dictk)
    return Response(json.dumps(lists), mimetype='application/json')
##### 词云图
@app.route('/cyun')
def cyun():
    return render_template('cyun.html')
##### 柱状图
@app.route('/zzt')
def zzt():
    return render_template('zzt.html')
##### 饼图
@app.route('/bt')
def bt():
    return render_template('bt.html')
##### 关系图
@app.route('/gxt')
def gxt():
    return render_template('gxt.html')
##### 折线图
@app.route('/zxt')
def zxt():
    return render_template('zxt.html')
##### 中国地图map-1
@app.route('/map1')
def map1():
    return render_template('map1.html')
##### 城市地图map-2
@app.route('/map2')
def map2():
    return render_template('map2.html')
##### 漏斗图
@app.route('/ldt')
def ldt():
    return render_template('ldt.html')
##### 词频统计
@app.route('/cptj')
def cptj():
    return render_template('cptj.html')





if __name__ == "__main__":
    """初始化,debug=True"""
    app.run(host='127.0.0.1', port=5000,debug=True)



